package xcmg.device.util;

import java.math.BigDecimal;

/**
 * @author wangyong
 */
public class DecimalUtil {

    private static final BigDecimal HUNDRED = BigDecimal.valueOf(100);

    /**
     * 存储时调整精度，乘以100再存储
     *
     * @param decimal
     * @return
     */
    public static BigDecimal roundDecimal4Enter(BigDecimal decimal) {
        if (null == decimal || decimal.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return HUNDRED.multiply(decimal);
    }

    public static BigDecimal multiplyHundred(BigDecimal num) {
        return getDecimal(num).multiply(new BigDecimal(100));
    }


    /**
     * 输出时再除以100
     *
     * @param decimal
     * @return
     */
    public static BigDecimal roundDecimal4Output(BigDecimal decimal) {
        if (null == decimal || decimal.compareTo(BigDecimal.ZERO) == 0) {
            return BigDecimal.ZERO;
        }
        return decimal.divide(HUNDRED, 2, BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal getDecimal(BigDecimal num) {
        if (num == null) {
            return BigDecimal.ZERO;
        }
        return num;
    }

    public static BigDecimal getStringDecimal(String num) {
        if (num == null) {
            return BigDecimal.ZERO;
        }
        try {
            return new BigDecimal(num);
        }catch (Exception e){
            return BigDecimal.ZERO;
        }
    }

    public static BigDecimal mutiply(BigDecimal num1, BigDecimal num2) {
        return getDecimal(num1).multiply(getDecimal(num2));
    }

    public static BigDecimal mutiplyReal(BigDecimal num1, BigDecimal num2) {
        return roundDecimal4Output(num1).multiply(roundDecimal4Output(num2));
    }

    public static Integer getInteger(Integer num) {
        return num == null ? 0 : num;
    }

    public static boolean convertTrueOrFalse(Integer num) {
        return getInteger(num) == 1;
    }

    /**
     * 计算方差
     */
    public static BigDecimal variance(BigDecimal[] x, int scale) {
        return new BigDecimal(variance(getDouble(x))).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }

    /**
     * 计算平均数
     */
    public static BigDecimal calAverage(BigDecimal[] x, int scale) {
        return new BigDecimal(calAverage(getDouble(x))).setScale(scale, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 计算平均数
     */
    public static double calAverage(double[] a) {
        double sum = 0;
        for (double anA : a) {
            sum += anA;
        }
        return sum / a.length;
    }

    /**
     * 求方差
     */
    public static double variance(double[] population) {
        double average = 0.0;
        for (double p : population) {
            average += p;
        }
        average /= population.length;

        double variance = 0.0;
        for (double p : population) {
            variance += (p - average) * (p - average);
        }
        return variance / population.length;
    }

    private static double[] getDouble(BigDecimal[] x) {
        double[] result = new double[x.length];
        for (int i = 0; i < x.length; i++) {
            if (null == x[i]) {
                result[i] = 0;
                continue;
            }
            result[i] = x[i].doubleValue();
        }
        return result;
    }


    /**
     * 牛顿迭代法求大数开方
     * Math.sqrt(Double x) 也可以，这里适合BigDecimal，不需要转
     *
     * @param x     需要开方的数值
     * @param scale 精确的位数
     * @return
     */
    public static BigDecimal extractRoot(BigDecimal x, int scale) {
        if (BigDecimal.ZERO.compareTo(x) == 0) {
            return BigDecimal.ZERO;
        }
        //开二次方
        BigDecimal base2 = BigDecimal.valueOf(2.0);
        BigDecimal deviation = x;
        int cnt = 0;
        while (cnt < 100) {
            deviation = (deviation.add(x.divide(deviation, 8, BigDecimal.ROUND_HALF_UP))).divide(base2, 8, BigDecimal.ROUND_HALF_UP);
            cnt++;
        }
        deviation = deviation.setScale(scale, BigDecimal.ROUND_HALF_UP);
        return deviation;
    }

    public static BigDecimal subtract(BigDecimal num1, BigDecimal num2) {
        return getDecimal(num1).subtract(getDecimal(num2));
    }

    public static boolean isZero(BigDecimal num) {
        return getDecimal(num).compareTo(BigDecimal.ZERO) == 0;
    }

    public static BigDecimal divideHundred(BigDecimal num) {
        return getDecimal(num).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP);
    }


    /**
     *@Description 元转换为分操作
     *@Author wzy
     *@Date 2020/9/10
     *@Time 19:53
     */
    public static BigDecimal yuan2fenDefauleZero(BigDecimal original){
        if(original == null){
            return BigDecimal.ZERO;
        }
        return original.multiply(new BigDecimal("100"));
    }

    /**
     *@Description 元转换为分操作
     *@Author wzy
     *@Date 2020/9/10
     *@Time 19:53
     */
    public static BigDecimal yuan2fen(BigDecimal original){
        if(original == null){
            return null;
        }
        return original.multiply(new BigDecimal("100"));
    }

    /**
     *@Description 分转换为元的操作
     *@Author wzy
     *@Date 2020/9/10
     *@Time 19:54
     */
    public static BigDecimal fen2yuan(BigDecimal original){
        if(original == null){
            return null;
        }
        return original.divide(new BigDecimal("100"));
    }
}
